#ifndef __RECTANGLE_H__
#define __RECTANGLE_H__
#include "hitable.h"
#include "hitable_list.h"

class xy_rect :public hitable {
public:
	xy_rect(){}
	xy_rect(float _x0, float _x1, float _y0, float _y1, float _k, material*mat) :
		x0(_x0), x1(_x1), y0(_y0), y1(_y1), k(_k), mp(mat) {};
	virtual bool hit(const ray&r, float t0, float t1, hit_record &rec)const;
	virtual bool bounding_box(float t0, float t1, aabb&box)const {
		box = aabb(vec3(x0, y0, k - 0.0001), vec3(x1, y1, k + 0.0001));
		return true;
	}
	material *mp;
	float x0, x1, y0, y1, k;
};

class xz_rect :public hitable {
public:
	xz_rect() {}
	xz_rect(float _x0, float _x1, float _z0, float _z1, float _k, material*mat) :
		x0(_x0), x1(_x1), z0(_z0), z1(_z1), k(_k), mp(mat) {};
	virtual bool hit(const ray&r, float t0, float t1, hit_record &rec)const;
	virtual bool bounding_box(float t0, float t1, aabb&box)const {
		box = aabb(vec3(x0, k - 0.0001, z0), vec3(x1, k + 0.0001, z1));
		return true;
	}
	material *mp;
	float x0, x1, z0, z1, k;
};
class yz_rect :public hitable {
public:
	yz_rect() {}
	yz_rect(float _y0, float _y1, float _z0, float _z1, float _k, material*mat) :
		y0(_y0), y1(_y1), z0(_z0), z1(_z1), k(_k), mp(mat) {};
	virtual bool hit(const ray&r, float t0, float t1, hit_record &rec)const;
	virtual bool bounding_box(float t0, float t1, aabb&box)const {
		box = aabb(vec3( k - 0.0001,y0, z0), vec3( k + 0.0001,y1, z1));
		return true;
	}
	material *mp;
	float y0, y1, z0, z1, k;
};

class flip_normals :public hitable {
public:
	flip_normals(hitable*p):ptr(p){}
	virtual bool hit(const ray&r,float t_min,float t_max,hit_record&rec)const{
		if (ptr->hit(r, t_min, t_max, rec)) {
			rec.normal = -rec.normal;
			return true;
		}
		else
			return false;
	}
	virtual bool bounding_box(float t0, float t1, aabb&box)const {
		return ptr->bounding_box(t0, t1, box);
	}
	hitable *ptr;
};

class box :public hitable {
public:
	box(){}
	box(const vec3&p0, const vec3&p1, material *ptr);
	virtual bool hit(const ray&r, float t0, float t1, hit_record&rec)const;
	virtual bool bounding_box(float t0, float t1, aabb&box)const {
		box = aabb(pmin, pmax);
		return true;
	}
	vec3 pmin, pmax;
	hitable *list_ptr;
};


#endif